//
//  ZeroFMDBManager.m
//  ZeroWorld
//
//  Created by 马进 on 2018/2/28.
//  Copyright © 2018年 马进. All rights reserved.
//

#import "ZeroFMDBManager.h"
#import <FMDB.h>

// 常用SQL
#define CREAT_TABLE_IFNOT_EXISTS             @"create table if not exists %@ (key text primary key, data blob)"
#define DELETE_DATA_WITH_PRIMARYKEY          @"delete from %@ where key = ?"
#define INSERT_TO_TABLE                      @"insert into %@ (key, data) values (?, ?)"
#define READ_DATA_TABLE_WITH_PRIMARYKEY      @"select data from %@ where key = ?"
#define READ_ALL_DATA                        @"select data from %@"
#define UPDATE_DATA_WHTH_PRIMARYKEY          @"update %@ set data = ? where key = ?"
#define CLEAR_ALL_DATA                       @"DELETE FROM %@"

static ZeroFMDBManager *_fmdbManager = nil;
@interface ZeroFMDBManager () <NSCopying, NSMutableCopying> {
    FMDatabase *_db;
}
@end

@implementation ZeroFMDBManager

+ (instancetype)shareDataBase {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _fmdbManager = [[ZeroFMDBManager alloc] init];
        [_fmdbManager initDataBase];
    });
    return _fmdbManager;
}

- (void)initDataBase {
    _db = [FMDatabase databaseWithPath:[self getDbPath]];
    [_db open];
    // 初始化所需要的数据表
    [_db close];
}

// 添加数据到某个表
- (BOOL)addDataWithTableName:(NSString *)tableName primaryKey:(NSString *)primaryKey data:(NSData *)data {
    BOOL ret = NO;
    if ([_db open]) {
        NSString *sql = [NSString stringWithFormat:CREAT_TABLE_IFNOT_EXISTS, tableName];
        ret = [_db executeUpdate:sql];
        if (ret) {
            //先删除再添加
            NSString *deleteSql = [NSString stringWithFormat:DELETE_DATA_WITH_PRIMARYKEY, tableName];
            ret = [_db executeUpdate:deleteSql,primaryKey];
            if (ret) {
                NSString *storeURL = [NSString stringWithFormat:INSERT_TO_TABLE, tableName];
                ret = [_db executeUpdate:storeURL,primaryKey,data];
            }
        }
    }
    [_db close];
    return ret;
}

- (BOOL)deleteDataWithTableName:(NSString *)tableName primaryKey:(NSString *)primaryKey {
    BOOL ret = false;
    if ([_db open]) {
        NSString *sql = [NSString stringWithFormat:CREAT_TABLE_IFNOT_EXISTS,tableName];
        ret = [_db executeUpdate:sql,primaryKey];
        if (ret) {
            NSString *deleteSql = [NSString stringWithFormat:DELETE_DATA_WITH_PRIMARYKEY,tableName];
            ret = [_db executeUpdate:deleteSql,primaryKey];
        }
    }
    [_db close];
    return ret;
}

- (BOOL)updateDataWithTableName:(NSString *)tableName primaryKey:(NSString *)primaryKey data:(NSData *)data {
    BOOL ret = false;
    if ([_db open]) {
        NSString *sql = [NSString stringWithFormat:CREAT_TABLE_IFNOT_EXISTS,tableName];
        ret = [_db executeUpdate:sql,primaryKey];
        if (ret) {
            NSString *updateSql = [NSString stringWithFormat:UPDATE_DATA_WHTH_PRIMARYKEY,tableName];
            ret = [_db executeUpdate:updateSql,data,primaryKey];
        }
    }
    [_db close];
    return ret;
}

- (BOOL)readDataWithTableName:(NSString *)tableName primaryKey:(NSString *)primaryKey data:(getDataByPrimaryKey)dataBlock {
    BOOL ret = false;
    if ([_db open]) {
        NSString *creatSql = [NSString stringWithFormat:CREAT_TABLE_IFNOT_EXISTS,tableName];
        ret = [_db executeUpdate:creatSql];
        if (ret) {
            NSString *readSql = [NSString stringWithFormat:READ_DATA_TABLE_WITH_PRIMARYKEY,tableName];
            FMResultSet *resultSet = [_db executeQuery:readSql,primaryKey];
            while ([resultSet next]) {
                NSData *data = [resultSet dataForColumn:@"data"];
                dataBlock(data);
            }
        }
    }
    [_db close];
    return ret;
}

- (BOOL)readAllDataWithTableName:(NSString *)tableName dataArr:(getAllData)allDataBlock {
    BOOL ret = false;
    NSMutableArray *dataArr = [NSMutableArray array];
    if ([_db open]) {
        NSString *sql = [NSString stringWithFormat:CREAT_TABLE_IFNOT_EXISTS,tableName];
        ret = [_db executeUpdate:sql];
        if (ret) {
            NSString *readSql = [NSString stringWithFormat:READ_ALL_DATA,tableName];
            FMResultSet *result = [_db executeQuery:readSql];
            while ([result next]) {
                NSData *data = [result dataForColumn:@"data"];
                [dataArr addObject:data];
            }
            allDataBlock(dataArr);
        }
    }
    [_db close];
    return ret;
}

- (BOOL)clearDataBaseWithTableName:(NSString *)tableName{
    BOOL ret = false;
    if ([_db open]) {
        NSString *clearSql = [NSString stringWithFormat:CLEAR_ALL_DATA,tableName];
        ret = [_db executeUpdate:clearSql];
    }
    [_db close];
    return ret;
}

- (NSString *)getDbPath {
    NSString *doc= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    return [doc stringByAppendingString:@"zeroData.sqlite"];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (_fmdbManager == nil) {
        _fmdbManager = [super allocWithZone:zone];
    }
    return _fmdbManager;
}

- (id)copy {
    return self;
}

- (id)mutableCopy {
    return self;
}

- (id)copyWithZone:(NSZone *)zone{
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}
@end
